use rbatis::{crud, impl_select_page, Page, rbdc::{self, db::ExecResult}, sql::{self, PageRequest}};
use serde::{Deserialize, Serialize};

use crate::pool;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TbApi {
    pub id: Option<u64>,
    pub path: String,
    pub description: String,
    pub apigroup: String,
    pub method: String,
}

crud!(TbApi {});
impl_select_page!(TbApi{select_page(query: &crate::handlers::api::Get) =>
    "`where 1=1`
    if query.path!=null && query.path!='':
        ` and path like #{'%'+query.path+'%'}`
    if query.description!=null && query.description!='':
        ` and description like #{'%'+query.description+'%'}`
    if query.apigroup!=null && query.apigroup!='':
        ` and apigroup like #{'%'+query.apigroup+'%'}`
    if query.method!=null && query.method!='':
        ` and method = #{query.method}`
    ` order by id asc`"
});

impl TbApi {
    pub async fn get_all_api() -> Result<Vec<TbApi>, rbdc::Error> {
        TbApi::select_all(pool!()).await
    }

    pub async fn insert_api(data: &mut TbApi) -> Result<ExecResult, rbdc::Error> {
        let result = TbApi::insert(pool!(), data).await?;
        data.id = Some(result.last_insert_id.clone().into());
        Ok(result)
    }

    pub async fn update_api(data: &TbApi) -> Result<ExecResult, rbdc::Error> {
        TbApi::update_by_column(pool!(), data, "id").await
    }

    pub async fn delete_api(id: u64) -> Result<ExecResult, rbdc::Error> {
        TbApi::delete_by_column(pool!(), "id", id).await
    }

    pub async fn get_apis(
        page: &crate::common::QueryPage,
        query: &crate::handlers::api::Get,
    ) -> Result<Page<TbApi>, rbdc::Error> {
        TbApi::select_page(pool!(), &PageRequest::from(page), query).await
    }
}
